<template>
  <el-dialog
    v-model="dialogVisible"
    title="添加系统变量"
    width="80%"
    :close-on-click-modal="false"
    :before-close="rest"
  >
    <!-- 添加设备 表单 -->
    <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-position="top">
      <el-row :gutter="28">
        <!-- 设备名称 -->
        <el-col :span="12">
          <el-form-item label="变量名称" prop="name">
            <el-input v-model="ruleForm.name" clearable @input="WriteName(ruleForm.name)" />
          </el-form-item>
        </el-col>
        <!-- 设备类型 级联选择器 -->
        <el-col :span="12">
          <el-form-item label="变量类型" prop="TaskGroupValue">
            <el-cascader
              style="width: 100%"
              v-model="selectList"
              :options="options"
              @change="selectChange(selectList)"
              :show-all-levels="false"
              placeholder="请选择设备类型"
              :props="{ value: 'DevicetypeValue', label: 'DevicetypeName' }"
            />
          </el-form-item>
        </el-col>
        <!-- 虚拟设备 -->
        <!-- 系统变量  -->

        <template v-if="selectList">
          <el-col
            ><div style="margin: 2% 0; font-size: 18px; font-weight: 600">
              {{ VirtualValue.DevicetypeName }}
            </div></el-col
          >
          <el-col v-for="(item, index) in VirtualValue.values" :key="index">
            <div style="display: flex">
              <!-- <el-input
                v-model="item.statusName"
                placeholder="请输入名称"
                style="flex: 1; margin: 2% 1% 2% 0"
              ></el-input> -->

              <div style="flex: 1; margin: 2% 0 2% 0">
                <el-select
                  v-model="ruleForm.SystemVariableType"
                  placeholder="请选择类型"
                  @change="changeType(ruleForm.SystemVariableType)"
                >
                  <el-option
                    v-for="(item, index) in VirtualJson[0]"
                    :key="index"
                    :label="item.name"
                    :value="item.value"
                  />
                </el-select>
              </div>

              <div style="flex: 1; margin: 2% 0 2% 2%; display: flex" v-if="!ExpressionShow">
                <el-input v-model="statusval" placeholder="请输入"></el-input>
              </div>
            </div>
            <div></div>
            <el-form-item v-if="ExpressionShow">
              <div class="flex gap-2" style="width: 100%">
                <el-tag v-for="tag in dynamicTags" :key="tag" :disable-transitions="false">
                  {{ tag.name }}
                </el-tag>

                <el-button
                  v-if="dynamicTags.length"
                  class="button-new-tag"
                  size="small"
                  type="danger"
                  @click="handleClose"
                >
                  删除
                </el-button>
              </div>
              <el-cascader
                style="margin: 1% 0"
                v-model="changeValue"
                :options="check1"
                :props="{
                  label: 'name',
                  value: 'statusName',
                  expandTrigger: 'hover'
                }"
                @change="handleChange"
              />
              <el-button @click="addition" type="primary" plain style="margin-left: 1%"
                >+</el-button
              >
              <el-button @click="subtraction" type="primary" plain>-</el-button>
              <el-button @click="multiplication" type="primary" plain>*</el-button>
              <el-button @click="division" type="primary" plain>/</el-button>
              <el-button @click="handleLeft" type="primary" plain>(</el-button>
              <el-button @click="handleRigth" type="primary" plain>)</el-button>
              <el-input
                v-if="inputVisible"
                ref="InputRef"
                v-model="inputValue"
                class="w-20"
                @keyup.enter="handleInputConfirm"
                @blur="handleInputConfirm"
                style="width: 100px; margin-left: 1%"
              />
              <el-button
                type="primary"
                plain
                v-if="!inputVisible"
                class="button-new-tag"
                @click="showInput"
                style="margin-left: 1%"
              >
                常量
              </el-button>
            </el-form-item>
          </el-col>
        </template>
      </el-row>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <!-- <el-button @click="dds">BaudRate</el-button> -->
        <el-button @click="rest">取消</el-button>
        <el-button type="primary" @click="submit"> 确定 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script>
import { ref, reactive, onMounted, nextTick } from 'vue'
import { useStore } from 'vuex'
import until from '../../until/csUntil/deviceUtils.js'
import VirtualDeviceJson from '../../MyJson/VirtualDevice.json'
import { v4 as uuidv4 } from 'uuid'
import { ElMessage } from 'element-plus'
export default {
  setup(_, { emit }) {
    // 在组件挂载后获取串口列表
    onMounted(() => {
      const deviceTypeStr = store.state.deviceTypeStr
      const device = JSON.parse(JSON.stringify(deviceTypeStr))
      const filterVirtual = device.children.filter((item) => item.isVirtual === 'IS_VARIABLE')
      options.value = filterVirtual
    })
    // vuex 实例对象
    const store = useStore()
    // dialog 显示隐藏
    const dialogVisible = ref(false)
    // JSON 字符串
    const VirtualJson = ref(VirtualDeviceJson.template)
    // 设备类型
    const options = ref([store.state.deviceTypeStr])
    // dialog 表单
    const ruleForm = ref({
      id: '',
      pid: '-1',
      name: '',
      Channels: -1,
      DevicetypeName: '',
      DevicetypeValue: null,
      isShow: '1',
      amplitude: '0',
      delay: '1',
      BaudRate: 9600,
      property: [],
      pins: [],
      values: [],
      version: '3.0',
      type: '485',
      dvcActualId: '1',
      isVirtual: 'IS_VARIABLE',
      ComPort: '',
      SystemVariableType: '',
      DeviceVariable: 'UNAVAILABLE',
      Expression: '',
      dynamicTags: []
    })
    // dialog 检验规则
    const rules = reactive({
      name: [{ required: true, message: '请输入任务名称', trigger: 'blur' }]
    })
    const Expression = ref('')
    // 表单实例对象·
    const ruleFormRef = ref(null)
    // 级联选择器选中的值
    const selectList = ref([])
    // 虚拟设备 筛选的值
    const VirtualValue = ref(null)
    // 表达式的显示
    const ExpressionShow = ref(false)
    // 选择的值
    const check1 = ref([])
    const changeValue = ref([])

    const inputValue = ref('')
    const dynamicTags = ref([])
    const inputVisible = ref(false)
    const InputRef = ref(null)
    const statusval = ref(null)

    // 设备类型 select  change 事件
    const selectChange = (data) => {
      dynamicTags.value = []
      // 系统变量
      ruleForm.value.DevicetypeValue = data[0]
      const res = until.findDeviceByValue(options.value, ruleForm.value.DevicetypeValue)
      res.values = res.property
      VirtualValue.value = JSON.parse(JSON.stringify(res))
      ruleForm.value.id = uuidv4()
      ruleForm.value.pins = []
      ruleForm.value.property = VirtualValue.value.property
      ruleForm.value.values = VirtualValue.value.property
      ruleForm.value.isShow = VirtualValue.value.isShow
      ruleForm.value.DevicetypeName = VirtualValue.value.DevicetypeName
      ruleForm.value.DevicetypeValue = VirtualValue.value.DevicetypeValue
    }

    // 提交表单
    const submit = () => {
      if (dynamicTags.value.length) {
        const cha1 = dynamicTags.value[dynamicTags.value.length - 1].name
        const result = regex1.value.test(cha1)
        const result2 = regex5.value.test(cha1)
        if (result || result2) {
          dynamicTags.value.splice(dynamicTags.value.length - 1, 1)
        }
        ruleForm.value.Expression = ''
        dynamicTags.value.forEach((item) => {
          ruleForm.value.Expression += item.value
        })
      } else {
        ruleForm.value.Expression = statusval.value
      }
      ruleForm.value.dynamicTags = dynamicTags.value
      ruleForm.value.values = VirtualValue.value.values

      ruleFormRef.value.validate((validate) => {
        if (validate) {
          const insertDvcAndDvcVersion = window.api.updateDvcAndDvcVersion(
            JSON.stringify(ruleForm.value)
          )
          if (insertDvcAndDvcVersion === '修改成功') {
            ElMessage.success('修改成功')
            rest()
            emit('update')
            dialogVisible.value = false
          } else {
            ElMessage.error(insertDvcAndDvcVersion)
          }
        }
      })
    }

    const WriteName = (data) => {
      if (ruleForm.value.DevicetypeValue === 1002) {
        VirtualValue.value.values[0].statusName = data
      }
    }

    const rest = () => {
      ruleForm.value.id = ''
      ruleForm.value.pid = '-1'
      ruleForm.value.name = ''
      ruleForm.value.Channels = -1
      ruleForm.value.DevicetypeName = ''
      ruleForm.value.DevicetypeValue = null
      ruleForm.value.isShow = '1'
      ruleForm.value.amplitude = '0'
      ruleForm.value.delay = '1'
      ruleForm.value.BaudRate = 9600
      ruleForm.value.values = []
      ruleForm.value.property = []
      ruleForm.value.pins = []
      ruleForm.value.version = '3.0'
      ruleForm.value.type = 'timer'
      ruleForm.value.dvcActualId = 'timer'
      ruleForm.value.isVirtual = 'IS_VARIABLE'
      ruleForm.value.ComPort = ''
      ruleForm.value.String = ''
      ruleForm.value.SystemVariableType = ''
      dialogVisible.value = false
      selectList.value = []
      dynamicTags.value = []
      inputValue.value = ''
      inputVisible.value = false
      changeValue.value = []
      check1.value = []
      statusval.value = null
      ExpressionShow.value = false
    }

    // 测试按钮
    const dds = () => {}

    // 类型选择
    const changeType = (data) => {
      if (data === 'EXPRESSION') {
        ExpressionShow.value = true
      } else {
        ExpressionShow.value = false
      }
      //
    }

    // 删除
    const handleClose = () => {
      dynamicTags.value.splice(dynamicTags.value.length - 1, 1)
    }

    // 点击数据切换成input 并且聚焦
    const showInput = () => {
      changeValue.value = []

      inputVisible.value = true
      nextTick(() => {
        InputRef.value[0].focus()
      })
    }

    // 加减乘除运算符（+、-、*、/）、小数点（.）数 正则
    const regex = ref(/^[\+\-\*\/\(\)]+$/)
    // 运算符
    const regex1 = ref(/^[\+\-\*\/]+$/)
    // 数字、小数点和汉字字符
    const regex2 = ref(/[\d.\u4e00-\u9fa5]+$/)
    // 数字
    const regex3 = ref(/^-?\d+(\.\d+)?$/)

    // 校验 value
    const regex4 = ref(/^[0-9A-Za-z{}._\-\u4e00-\u9fa5]+$/)

    // 失焦 或者回车 保存值
    const handleInputConfirm = () => {
      if (dynamicTags.value.length) {
        // tag 最后一位
        const char1 = dynamicTags.value[dynamicTags.value.length - 1]?.name
        // input 正在输入的值
        const char2 = inputValue.value

        // 校验 加减乘除
        const result1 = regex1.value.test(char1)
        // 校验 数字小数点 和汉字
        const result2 = regex3.value.test(char1)

        // 校验 加减乘除
        const result3 = regex1.value.test(char2)
        // 校验 数字小数点 和汉字
        const result4 = regex3.value.test(char2)
        // 校验左边括号
        const result5 = regex5.value.test(char1)
        // 当前输入数字 ， 上次输入运算符
        if (result4 && result1) {
          dynamicTags.value.push({ name: inputValue.value, value: inputValue.value })
        }
        // 当前输入运算符  ， 上次输入数字
        if (result3 && result2) {
          dynamicTags.value.push({ name: inputValue.value, value: inputValue.value })
        }
        if (result5) {
          dynamicTags.value.push({ name: inputValue.value, value: inputValue.value })
        }
        inputVisible.value = false
        inputValue.value = ''
        // 当前输入的值和tag最后输入的值匹配
      } else {
        // 第一次输入的值为数字
        const result = regex3.value.test(inputValue.value)
        // 运算符

        if (result) {
          dynamicTags.value.push({ name: inputValue.value, value: inputValue.value })
        }
        inputVisible.value = false
        inputValue.value = ''
      }
    }

    // 级联选择器 change事件
    const handleChange = (changeValue) => {
      // tag 最后一位
      const char1 = dynamicTags.value[dynamicTags.value.length - 1]?.name

      const result = regex.value.test(char1)

      const char2 = dynamicTags.value[dynamicTags.value.length - 1]

      if (result || !char2) {
        if (changeValue.length === 2) {
          check1.value.forEach((item) => {
            if (item.statusName === changeValue[0]) {
              item.children.forEach((child) => {
                if (child.statusName === changeValue[1]) {
                  dynamicTags.value.push({
                    name: `${item.name}.${child.name}`,
                    value: `{${changeValue[0]}.${changeValue[1]}}`
                  })
                }
              })
            }
          })
        }
        if (changeValue.length === 1) {
          check1.value.forEach((item) => {
            if (item.SystemVariableType === 'EXPRESSION') {
              if (item.id === changeValue[0]) {
                dynamicTags.value.push({
                  name: `${item.name}`,
                  value: `{${changeValue[0]}.SystemVariable}`
                })
              }
            }
            if (item.SystemVariableType === 'NUMBER') {
              if (item.id === changeValue[0]) {
                dynamicTags.value.push({
                  name: `${item.name}`,
                  value: `${item.Expression}`
                })
              }
            }
          })
        }
      }
    }

    const addition = () => {
      changeValue.value = []
      // tag 最后一位
      const char1 = dynamicTags.value[dynamicTags.value.length - 1]?.value
      const char3 = dynamicTags.value[dynamicTags.value.length - 1]?.name
      // 替换运算符
      const result2 = regex1.value.test(char3)
      // input 正在输入的值
      const char2 = '+'

      // 校验 数字小数点 和汉字
      const result = regex4.value.test(char1)
      if (char1 && result && !result2) {
        dynamicTags.value.push({ name: char2, value: char2 })
      }
      // 替换运算符
      const result1 = regex1.value.test(char1)
      if (result1) {
        handleClose()
        dynamicTags.value.push({ name: char2, value: char2 })
      }
    }
    const subtraction = () => {
      changeValue.value = []

      // tag 最后一位
      const char1 = dynamicTags.value[dynamicTags.value.length - 1]?.value
      const char3 = dynamicTags.value[dynamicTags.value.length - 1]?.name
      // input 正在输入的值
      const char2 = '-'

      // 校验 数字小数点 和汉字
      const result = regex4.value.test(char1)
      // 替换运算符
      const result2 = regex1.value.test(char3)
      if (char1 && result && !result2) {
        dynamicTags.value.push({ name: char2, value: char2 })
      }
      // 替换运算符
      const result1 = regex1.value.test(char1)
      if (result1) {
        handleClose()
        dynamicTags.value.push({ name: char2, value: char2 })
      }
    }
    const multiplication = () => {
      changeValue.value = []

      // tag 最后一位
      const char1 = dynamicTags.value[dynamicTags.value.length - 1]?.value
      const char3 = dynamicTags.value[dynamicTags.value.length - 1]?.name
      // 替换运算符
      const result2 = regex1.value.test(char3)
      // input 正在输入的值
      const char2 = '*'

      // 校验 数字小数点 和汉字
      const result = regex4.value.test(char1)
      if (char1 && result && !result2) {
        dynamicTags.value.push({ name: char2, value: char2 })
      }
      // 替换运算符
      const result1 = regex1.value.test(char1)
      if (result1) {
        handleClose()
        dynamicTags.value.push({ name: char2, value: char2 })
      }
    }
    const division = () => {
      changeValue.value = []

      // tag 最后一位
      const char1 = dynamicTags.value[dynamicTags.value.length - 1]?.value
      const char3 = dynamicTags.value[dynamicTags.value.length - 1]?.name
      // 替换运算符
      const result2 = regex1.value.test(char3)
      // input 正在输入的值
      const char2 = '/'

      // 校验 数字小数点 和汉字
      const result = regex4.value.test(char1)
      if (char1 && result && !result2) {
        dynamicTags.value.push({ name: char2, value: char2 })
      }
      // 替换运算符
      const result1 = regex1.value.test(char1)
      if (result1) {
        handleClose()
        dynamicTags.value.push({ name: char2, value: char2 })
      }
    }

    // 匹配左括号
    const regex5 = ref(/^\($/)
    // 匹配右括号
    const regex6 = ref(/^\)$/)

    const handleLeft = () => {
      changeValue.value = []
      // tag 最后一位
      const char1 = dynamicTags.value[dynamicTags.value.length - 1]?.value
      // const char3 = dynamicTags.value[dynamicTags.value.length - 1]?.name
      const char2 = '('

      const result = regex1.value.test(char1)
      if (result || char1 === undefined) {
        dynamicTags.value.push({ name: char2, value: char2 })
      }
    }

    const handleRigth = () => {
      changeValue.value = []
      // tag 最后一位
      const char1 = dynamicTags.value[dynamicTags.value.length - 1]?.value
      // const char3 = dynamicTags.value[dynamicTags.value.length - 1]?.name
      // input 正在输入的值
      const char2 = ')'

      // 校验 数字小数点 和汉字
      const result = regex1.value.test(char1)
      const result1 = regex6.value.test(char1)
      const result2 = regex5.value.test(char1)
      if (char1 && !result && !result1 && !result2) {
        dynamicTags.value.push({ name: char2, value: char2 })
      }
    }

    const openDialog = (tableData, data) => {
      ruleForm.value = tableData
      selectList.value.push(tableData.DevicetypeValue)
      VirtualValue.value = tableData
      dynamicTags.value = tableData.dynamicTags
      statusval.value = tableData.Expression
      if (dynamicTags.value.length) {
        ExpressionShow.value = true
      }

      const listDvcAndDvcVer = window.api.listDvcAndDvcVer()
      const res = JSON.parse(listDvcAndDvcVer)
      res.forEach((item) => {
        if (item.ComPort && item.pid === '-1') {
          item.children = item.property
          item.children.forEach((e) => {
            e.name = e.propertyName
          })
          item.statusName = item.id
          check1.value.push(item)
        }
        if (item.isVirtual === 'IS_VIRTUAL') {
          item.children = []
          item.property.forEach((e) => {
            if (e.ShowPageType === 'DIGITAL') {
              e.name = e.propertyName
              item.children.push(e)
            }
          })
          item.statusName = item.id
          check1.value.push(item)
        }
      })

      let FishbowlList = {
        name: '系统设置',
        id: '1234567890',
        statusName: '1234567890',
        children: []
      }
      const dds = JSON.parse(listDvcAndDvcVer)
      const getmylist = dds.filter((item) => item.id === '1234567890')
      const ddss = JSON.parse(JSON.stringify(getmylist))
      FishbowlList.children = ddss[0]?.property
      FishbowlList.children.forEach((item) => {
        item.name = item.propertyName
        item.id = item.deviceId
      })
      check1.value.push(FishbowlList)

      if (data) {
        data.forEach((item) => {
          if (item.SystemVariableType === 'EXPRESSION' || item.SystemVariableType === 'NUMBER') {
            item.statusName = item.id
            check1.value.push(item)
          }
        })
      }

      dialogVisible.value = true
    }

    // 修改
    // const OpenDialogVisible = (data) => {
    //   changeType(data.SystemVariableType)
    //   ruleForm.value = data
    //   selectList.value.push(data.DevicetypeValue)
    //   VirtualValue.value = data
    //   dynamicTags.value = data.dynamicTags
    //   statusval.value = data.Expression
    //   dialogVisible.value = true
    // }
    return {
      dialogVisible,
      options,
      ruleForm,
      selectList,
      VirtualValue,
      ruleFormRef,
      VirtualJson,
      rules,
      ExpressionShow,
      Expression,
      check1,
      changeValue,
      inputValue,
      dynamicTags,
      inputVisible,
      InputRef,
      statusval,
      addition,
      subtraction,
      multiplication,
      division,
      selectChange,
      submit,
      rest,
      WriteName,
      changeType,
      handleClose,
      showInput,
      handleInputConfirm,
      handleChange,
      handleRigth,
      handleLeft,
      openDialog
    }
  }
}
</script>

<style>
</style>